package main

import (
	"fmt"
	"math"
	"math/cmplx"
	"strconv"
)

var (
	// 注意, func(函数)外不能使用 := 来定义变量
	// go中没有全局变量概念, 只有包内变量(同一个包下面可用)
	flag = true
)

const (
	//指定了类型情况下, 会进行类型强校验
	filename string = "abc.txt"
	//不指定类型情况下, 后续可以使用 int float类型进行接收, 不会进行类型强校验
	digit1, digit2 = 4, 7
)

const (
	//不直接赋值, 使用 iota 进行自增, 开始为0
	//cpp = 0
	cpp = iota
	//忽略 1 的值
	_
	//java = 2
	java
	//python =3
	python
	//golang =4
	golang
)

// b, kb, mb, gb, tb, pb
const (
	b = 1 << (10 * iota)
	kb
	mb
	gb
	tb
	pb
)

func main() {
	/*variableInitialValue()
	euler()
	enums()*/
	var str []byte = nil
	fmt.Println("str=", string(str))
	typeTest()
}

func typeTest() {
	var num int = 777
	var num32 int32 = 888
	var num64 int64 = 999
	parseInt, _ := strconv.ParseInt("11", 10, 64)
	typeMap := map[string]interface{}{
		"1":   parseInt,
		"int": strconv.Itoa(num),
		"32":  strconv.FormatInt(int64(num32), 10),
		"64":  strconv.FormatInt(num64, 10),
	}
	for k, v := range typeMap {
		switch vv := v.(type) {
		case string:
			fmt.Println(k, "is string", vv)
		case int:
			fmt.Println(k, "is int ", vv)
		case float64:
			fmt.Println(k, "is float64 ", vv)
		case []interface{}:
			fmt.Println(k, "is array:")
			for i, j := range vv {
				fmt.Println(i, j)
			}
		}
	}
}

/*
类型
bool string
//int不指定长度则根据系统位数适配, u表示无符号, uintptr指针
(u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr
//byte 1字节, rune(类似char类型) 字符类型, 4字节(为了兼容中文等编码)
byte rune
//float 浮点数, complex 复数
float32, float32, complex64, float128
//规定(虚数, 想象的数, image, 平方是负数的或根号内是负数的数), i = √-1 (根号-1)
复数: 3 + 4i
| 3 + 4i| = √(3^2 + 4^2) = 5
i^2 (平方) = -1, i^3 = -i, i^4 = 1
*/
func variableDefaultValue() {
	//声明即有默认值
	var digit int
	var str string
	// %q 格式化为携带双引号样式
	fmt.Printf("%d %q \n", digit, str)
}

func variableInitialValue() {
	var digit1, digit2 int = 6, 7
	//可以省略类型 strng
	var str = "gin"
	// := 可以省略var
	str2 := "gin2"
	digit3, str3 := 8, "gin3"
	// %q 格式化为携带双引号样式
	fmt.Printf("%d %d %d %q %q %q \n", digit1, digit2, digit3, str, str2, str3)
}

func euler() {
	//复数, 二维数, 自然数为X轴上的长度, 虚数为Y轴上的长度
	//3自然数, 4i虚数
	c := 3 + 4i
	//计算绝对值, 3,4 勾股定理=5
	fmt.Println(cmplx.Abs(c))
	//欧拉公式, 理论值是0, 但是go(大多数语言)浮点数不准, 结果为 (0+1.2246467991473515e-16i), 接近于0
	fmt.Println(cmplx.Pow(math.E, 1i*math.Pi) + 1)
	//精确到小数点后三位
	fmt.Printf("%.3f \n", cmplx.Pow(math.E, 1i*math.Pi)+1)

}

func triangle() {
	//go 必须显示强制类型装换
	// 数字比较大, 可能会有误差(float不准的问题), 接近实际值
	var a, b int = 3, 4
	var c float64
	c = math.Sqrt(float64(a*a + b*b))
	fmt.Println(c)
}

func calcTriangle(a, b int) int {
	var c float64
	c = math.Sqrt(float64(a*a + b*b))
	return int(c)
}

func enums() {
	fmt.Println(cpp, java, python, golang)
	fmt.Println(b, kb, mb, gb, tb, pb)
}
